package club.kynb.mall.application.repository.impl;

import club.kynb.mall.application.model.model.dto.PreviewOrderDTO;
import club.kynb.mall.application.repository.OrderRepository;
import club.kynb.mall.product.dto.ProductSpuDetailDTO;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author kynb_club@163.com
 * @since 2021/7/6 9:49 下午
 */
@Slf4j
@Component
@AllArgsConstructor
public class OrderRepositoryImpl implements OrderRepository {
    private final StringRedisTemplate stringRedisTemplate;
    private static final ObjectMapper objectMapper = new ObjectMapper();

    private static final String PREVIEW_ORDER_KEY = "PREVIEW_ORDER:%s";
    private static final String PREVIEW_ORDER_SPU_LIST_KEY = "PREVIEW_ORDER_SPU_LIST:%s";

    @Override
    public void savePreOrder(String innerOrderNo, PreviewOrderDTO previewOrderDTO) {
        final String jsonStr = JSONUtil.toJsonStr(previewOrderDTO);
        stringRedisTemplate.opsForValue().set(String.format(PREVIEW_ORDER_KEY, innerOrderNo), jsonStr, 60, TimeUnit.MINUTES);
    }

    @Override
    public void savePreOrderSpuList(String innerOrderNo, List<ProductSpuDetailDTO> filteredSpuList) {
        final String jsonStr = JSONUtil.toJsonStr(filteredSpuList);
        stringRedisTemplate.opsForValue().set(String.format(PREVIEW_ORDER_SPU_LIST_KEY, innerOrderNo), jsonStr, 60, TimeUnit.MINUTES);
    }

    @Override
    public PreviewOrderDTO getPreOrder(String innerOrderNo) {
        final String jsonStr = stringRedisTemplate.opsForValue().get(String.format(PREVIEW_ORDER_KEY, innerOrderNo));
        return JSONUtil.toBean(jsonStr, PreviewOrderDTO.class);
    }

    @Override
    public List<ProductSpuDetailDTO> getPreOrderSpuList(String innerOrderNo) {
        List<ProductSpuDetailDTO> itemList = new ArrayList<>();
        final String jsonStr = stringRedisTemplate.opsForValue().get(String.format(PREVIEW_ORDER_SPU_LIST_KEY, innerOrderNo));
        if (StrUtil.isBlank(jsonStr)){
            return itemList;
        }
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ProductSpuDetailDTO.class);
        try {
            itemList = objectMapper.readValue(jsonStr, javaType);
        } catch (JsonProcessingException e) {
            log.error("JSON反序列化失败", e);
        }
        return itemList;
    }

    @Override
    public void clearPreOrderCache(String innerOrderNo) {
        stringRedisTemplate.opsForValue().set(String.format(PREVIEW_ORDER_SPU_LIST_KEY, innerOrderNo),"",0,TimeUnit.MILLISECONDS);
        stringRedisTemplate.opsForValue().set(String.format(PREVIEW_ORDER_KEY, innerOrderNo),"",0,TimeUnit.MILLISECONDS);
    }

}
